/**
 * Copyright 2014 @ z3q.net.
 * name :
 * author : jarryliu
 * date : 2013-12-08 10:47
 * description :
 * history :
 */

package sale

import (
    "errors"
	"strings"
	"dhfshop/models"
	"github.com/astaxie/beego/orm"
)

/* 商品类目结构 */
type ItemCat struct {
	PartnerId int64      `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`       //
	StoreId   int64      `orm:"column(store_id)" json:"store_id" form:"store_id"`          /* 店铺ID */
	Cid       int64    `orm:"column(cid);pk;auto" json:"cid" form:"cid"`                 /* 类目 id */
    ParentCid int64    `orm:"column(parent_cid);null" json:"parent_cid" form:"parent_cid"`  /* 父类目ID=0时，代表的是一级的类目 */
    Name      string   `orm:"column(name);size(128);null" json:"name" form:"name"`       /* 类目名称 */
    Lft       int32    `orm:"column(lft);null" json:"-"`       
    Rgt       int32    `orm:"column(rgt);null" json:"-"`       
    Level     int32    `orm:"column(level);null" json:"level"`                          /* 类目层级 */
	Sort      int      `orm:"column(sort);default(0)" json:"sort" form:"sort"`          /*排序字段*/
}

func init() {
    orm.RegisterModel(new(ItemCat))   
}

func InitDefaultRootCid(partnerId, storeId int64){
    exist := existRootCid(partnerId, storeId)
    if !exist {
	    v := ItemCat{}
		v.PartnerId = partnerId
	    v.StoreId = storeId
		v.Name = "商品"
		v.ParentCid = 0
	    v.Lft = 1
	    v.Rgt = 2
	    v.Level = 1
	    AddItemCat(&v)
	}
}
func existRootCid(partnerId, storeId int64) bool {
    o := models.GetDefaultDB()
	exist := o.QueryTable(new(ItemCat)).Filter("partner_id",partnerId).Filter("store_id",storeId).Filter("parent_cid",0).Exist()
	return exist
}

func AddItemCat(m *ItemCat) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func GetItemCatById(id int64) (v *ItemCat, err error) {
	o := models.GetDefaultDB()
	v = &ItemCat{Cid: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func UpdateItemCatById(m *ItemCat,k ...string) (err error) {
	o := models.GetDefaultDB()
	v := ItemCat{Cid: m.Cid}
	if err = o.Read(&v); err == nil {
		if _, err = o.Update(m, k...); err == nil {
			return
		}
	}
	return
}

func DeleteItemCat(id int64) (err error) {
	o := models.GetDefaultDB()
	v := ItemCat{Cid: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&ItemCat{Cid: id}); err == nil {
			return
		}
	}
	return
}

func GetAllItemCats(storeIds []int64,query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*ItemCat, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(ItemCat))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	if len(storeIds) > 0 {
        qs = qs.Filter("store_id__in", storeIds)
    }
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*ItemCat
	if _, err = qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		return lists, cnt, nil
	}
	return nil, 0, err
}

func BatchAddCid(m *ItemCat, parentLft int32) (id int64, err error) {
	o := models.GetDefaultDB()
	o.Begin()
	id, err = o.Insert(m)
	if err != nil {
		o.Rollback()
		return id, err	
	}
	var r orm.RawSeter
    r = o.Raw("UPDATE item_cat SET rgt = rgt + 2 WHERE rgt > ?", parentLft)
	_, err = r.Exec()
	if err != nil {
		o.Rollback()
		return id, err	
	}
    r = o.Raw("UPDATE item_cat SET lft = lft + 2 WHERE lft > ?", parentLft)
	_, err = r.Exec()
	if err != nil {
		o.Rollback()
		return id, err	
	}
	o.Commit()
	return id, nil
}


